#include "myc.h"

struct token *endbr(struct token *st,struct token *end) {
	int rou=0,squ=0,cur=0;
	while (st!=end) {
		if (tokis(st,"(")) rou++;
		if (tokis(st,"[")) squ++;
		if (tokis(st,"{")) cur++;
		if (tokis(st,")")) rou--;
		if (tokis(st,"]")) squ--;
		if (tokis(st,"}")) cur--;
		if (!rou && !squ && !cur) return st;
		st=st->next;
		if (rou<0) error("unexpected )");
		if (squ<0) error("unexpected ]");
		if (cur<0) error("unexpected }");
	}
	if (rou) error("missing )");
	if (squ) error("missing ]");
	if (cur) error("missing }");
	return NULL;
}

struct token *stabr(struct token *st,struct token *end) {
	int rou=0,squ=0,cur=0;
	while (st!=end) {
		end=end->prev;
		if (tokis(end,")")) rou++;
		if (tokis(end,"]")) squ++;
		if (tokis(end,"}")) cur++;
		if (tokis(end,"(")) rou--;
		if (tokis(end,"[")) squ--;
		if (tokis(end,"{")) cur--;
		if (!rou && !squ && !cur) return end;
		if (rou<0) error("missing )");
		if (squ<0) error("missing ]");
		if (cur<0) error("missing }");
	}
	if (rou) error("unexpected )");
	if (squ) error("unexpected ]");
	if (cur) error("unexpected }");
	return NULL;
}

struct token *find_leftest(struct token *st,struct token *end,char *pat) {
	while (st!=end) {
		if (is_brack(st)) st=endbr(st,end);
		else if (tokis(st,pat)) return st;
		st=st->next;
	}
	return NULL;
}

struct token *find_rightest(struct token *st,struct token *end,char *pat) {
	while (st!=end) {
		end=end->prev;
		if (is_brack(end)) end=stabr(st,end->next);
		else if (tokis(end,pat)) return end;
	}
	return NULL;
}

int tokis(struct token* tok,char* st) {
	while (1) {
		if (!strncmp(tok->str,st,tok->len) && (st[tok->len]==' ' || !st[tok->len])) return 1;
		st=strchr(st,' ');
		if (!st++) return 0;
	}
}

int toktoint(struct token *tok) {
	int i,res=0;
	for (i=0;i<tok->len;i++) res=res*10+tok->str[i]-'0';
	return res;
}

int is_letter(char c) {
	return isalpha(c) || c=='_';
}

int is_alnum(char c) {
	return isalnum(c) || c=='_';
}

int is_brack(struct token *tok) {
	return tokis(tok,"( ) [ ] { }");
}
